<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WeakRef</title>
</head>
<body>
  <script>
    // WeakSet 和 WeakMap 是基于弱引用的数据结构，ES2021 更进一步，提供了 WeakRef 对象，用于直接创建对象的弱引用。
    var target = {};
    var wr = new WeakRef(target);
    console.log(wr)// WeakRef {}
    /**
     * 上面示例中，target是原始对象，构造函数WeakRef()创建了一个基于target的新对象wr.这里wr就是
     * 一个WeakRef的实例，属于对target的弱引用，垃圾回收机制不会计入这个引用
     * 也就是说，wr的引用不会妨碍原始对象target被垃圾回收机制清除。
     *
     * WeakRef 实例对象有一个deref()方法，如果原始对象存在，该方法返回原始对象;
     * 如果原始对象已经被垃圾回收机制清除，该方法返回undefined
    */
   var target = {};
   var wr = new WeakRef(target);
   var obj = wr.deref();
   if (obj) {
     console.log('target未被垃圾回收机制清除')
   }
   /**
    * 上面示例中，deref()方法可以判断原始对象是否已被清除。
    * 弱引用对象的一大用处，就是作为缓存，未被清除时可以从缓存取值
    * 一旦清除缓存就自动失效。
   */
  function makeWeakCached(f) {
    var cache = new Map();
    return key => {
      var ref = cache.get(key);
      if(ref) {
        var cached = ref.deref();
        if (cached !== undefined) return cached;
      }
      var fresh = f(key);
      cache.set(key, new WeakRef(fresh));
      return fresh;
    }
  }
  var getImageCached = makeWeakCached(getImage)
  /**
   * 上面示例中，makeWeakCached()用于建立一个缓存，缓存里面保存对原始文件的弱引用
   标准规定，一旦使用weakRef创建了原始对象的弱引用，那么在本轮事件循环， 原始对象肯定不会被清除，之后在
   后面的事件循环才会被清除。
  */
  </script>
</body>
</html>